import { Sql, SQL_SYMBOLE } from '../../sql';
import { KeyColumns, KeyColumnsObject } from './key-column';
import { overload } from '../../../../util';

export class PrimaryKey extends Sql {
  static isPrimaryKey(object: any): object is PrimaryKey {
    return object?.$type === SQL_SYMBOLE.PRIMARY_KEY;
  }
  readonly $type: SQL_SYMBOLE.PRIMARY_KEY = SQL_SYMBOLE.PRIMARY_KEY;
  $name?: string;
  /**
   * 声明为非聚焦主键
   */
  $nonclustered: boolean = false;
  $columns?: KeyColumns;

  constructor(
    name?: string,
    columns?: KeyColumns | string[] | KeyColumnsObject
  ) {
    super();
    this.$name = name;
    if (columns) {
      this.on(columns);
    }
  }

  on(columns: KeyColumns | string[] | KeyColumnsObject): this;
  on(...columns: string[]): this;
  on(...args: [KeyColumns | string[] | KeyColumnsObject] | string[]): this {
    if (this.$columns) {
      throw new Error(`Columns is defined.`);
    }
    if (args.length === 0) {
      throw new Error(`Primary key must have a column.`);
    }
    let keyColumns: KeyColumns;
    if (typeof args[0] === 'string') {
      keyColumns = (args as string[]).map(name => ({
        name,
        sort: 'ASC',
      }));
    } else if (Array.isArray(args[0])) {
      if (typeof args[0][0] === 'string') {
        keyColumns = (args[0] as string[]).map(name => ({
          name,
          sort: 'ASC',
        }));
      } else {
        keyColumns = args[0] as KeyColumns;
      }
    } else if (typeof args[0] === 'object') {
      if (Reflect.get(args[0], 'name') && Reflect.get(args[0], 'sort')) {
        // 如果是单个 KeyColumn
        keyColumns = args as unknown as KeyColumns;
      } else {
        keyColumns = Object.entries(args[0] as KeyColumnsObject).map(
          ([name, sort]) => ({
            name,
            sort,
          })
        );
      }
    } else {
      throw new Error(`Invalid arguments.`);
    }
    this.$columns = keyColumns;
    return this;
  }

  withNoclustered(): this {
    this.$nonclustered = true;
    return this;
  }
}
